/**
 * Copyright (C) 2011 Ron Coleman. Contact: ronncoleman@gmail.com
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package bj.gui

import javax.swing.event.ChangeEvent
import scala.swing.SimpleGUIApplication
import scala.swing.event
import java.awt.event.ActionListener
import event.ButtonClicked
import scala.swing._
import java.awt.Dimension
import java.awt.Color
import BorderPanel.Position._
import scala.swing.TextField
import java.awt.image.BufferedImage
import javax.swing.ImageIcon
import javax.swing.event.ChangeListener
import scala.swing.event.ActionEvent
import com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel
import bj.util.Logs
import org.apache.log4j.PropertyConfigurator
import scala.actors.OutputChannel
import scala.actors.Actor
import scala.actors.Actor._
import bj.card.Card
import bj.hkeeping.Broke
import bj.actor._
import javax.imageio.ImageIO
import java.io.File
import scala.actors.remote.RemoteActor._
import scala.actors.remote.Node
import scala.actors.remote.RemoteActor
import bj.util._
import bj.util.Config._
import scala.actors.AbstractActor

/**
 * @author Vikram
 * This class is a User Interface which enables a the UI to play this BlackJack game
 *
 */

class HumanGui extends Frame with Logs {
  javax.swing.UIManager.setLookAndFeel(new NimbusLookAndFeel)
  PropertyConfigurator.configure("log4j.properties")

  RemoteActor.classLoader = getClass.getClassLoader

  /** Remote MailBox(Abstract Actor) for the House */
  var house = select(Node(LoginScreen.SERVER, LoginScreen.PORT), HouseServiceName)

  /** dealer mail box */
  var dealer: OutputChannel[Any] = null

  /** Initializing the Buffer image to null */
  var bufferedImage: BufferedImage = null

  /** Player BankRoll */
  var newBankRoll = LoginScreen.bankRoll

  /** Player Bet Amount */
  var betAmt = LoginScreen.betAmt

  /** Player Name */
  var playerName = LoginScreen.playerName

  /** Shuffling seed for shoe */
  var seed = LoginScreen.seed

  /** creating me as Abstract Actor and initilizing to null */
  var me: AbstractActor = null

  /** Player Id */
  var pid = -1

  /** Boolean variable flag set to Flase */
  var flag: Boolean = false

  def top = mainFrame

  /** Creating new Mainframe */
  val mainFrame = new MainFrame {
    println("Welcome to Play BlackJack")
    title = "BlackjackGameScreen"
    minimumSize = new Dimension(760, 560)
    resizable = false

    /** Creating Object for TextField - BetAmount */
    object betAmount extends TextField {
      columns = 5
      text = betAmt.toString()
    }

    /** Creating Object for TextField - Shuffling Seed */
    object shuffleSeed extends TextField {
      columns = 3
      text = seed.toString()
    }

    /** Creating Object for TextField - BankRoll */
    object bankRol extends TextField {
      columns = 7
      text = newBankRoll.toString()
      editable = false
    }

    /** Creating Deal Button */
    val dealButton = new Button { text = "   DEAL  " }

    /** Creating Quit Button */
    val quitButton = new Button { text = "   QUIT  " }

    /** Creating Hit Button */
    val hitButton = new Button {
      text = "    HIT    "
      enabled = false
    }

    /** Creating Stay Button */
    val stayButton = new Button {
      text = "   STAY   "
      enabled = false
    }

    /** Creating Double Down Button */
    val doubleButton = new Button {
      text = "DOUBLE"
      enabled = false
    }

    /** Creating Dealers Upcard Label */
    val dealerUpCard = new Label { icon = cardImage("back1") }

    /** Creating Dealers Holecard Label */
    val dealerDownCard = new Label { icon = cardImage("back") }

    /** Creating Dealers Name Label */
    val dealerName = new Label {
      text = "Jack Black"
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating HumanPlayer Name Label */
    val humanPlayerName = new Label {
      text = playerName
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating BetterPlayer Name Label */
    val botPlayerName = new Label {
      text = "RonBot"
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating BetAmount Label */
    val betAmtLabel = new Label {
      text = "Bet Amount: $"
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating BetAmount value Label */
    val betAmtValue = new Label {
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating ActionLabel Label */
    val actionLabel = new Label {
      text = "Bot Action: "
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating ActionValue Label */
    val actionValue = new Label {
      text = "-"
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating BankRol Label for Better Player */
    val bankRollLabel = new Label {
      text = "Bank Roll: $ "
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating BankRolValue Label for Better Player */
    val bankRollValue = new Label {
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating BankRol Label for Human Player */
    val bankRolLabel = new Label {
      text = "Bank Roll: $"
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating BankRol Label for Human Player */
    val bankRolValue = new Label {
      text = newBankRoll.toString()
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating MinBet Label for Table assigned and displayed */
    val minBetLabel = new Label {
      text = "Table Min bet  : $"
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating MinBet Value for Table assigned and displayed */
    val minBetValue = new Label {
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating MaxBet Label for Table assigned and displayed */
    val maxBetLabel = new Label {
      text = "Table Max bet : $"
      font = new Font("Segoe UI Semibold", 0, 15)
    }

    /** Creating MaxBet Value for Table assigned and displayed */
    val maxBetValue = new Label {
      font = new Font("Segoe UI Semibold", 0, 15)
      foreground = new java.awt.Color(255, 255, 255)
    }

    /** Creating Dealer Cards panel and addng Dealer Upcard and hole card */
    val dealerCards = new FlowPanel() {
      preferredSize = new java.awt.Dimension(600, 60)
      contents += dealerUpCard
      contents += dealerDownCard
      opaque = false
    }

    /**
     *  Creating Horizontal Label at the center of the table
     *  to display animations used in the Game
     */
    val hGapPanel = new BoxPanel(Orientation.Horizontal) {
      preferredSize = new java.awt.Dimension(100, 60)
      contents += new Label { preferredSize = new java.awt.Dimension(100, 60) }
      opaque = false
      resizable = false
    }

    /** Creating Player Cards panel which contains Humanplayer cards */
    val humanPlayerCards = new FlowPanel {
      preferredSize = new java.awt.Dimension(310, 60)
      opaque = false
      resizable = false
    }

    /**
     *  Creating Player message box which displays Broke
     *  or BlackJack messages for Human Player
     */
    val humanPlayerMsg = new FlowPanel {
      opaque = false
      resizable = false
    }

    /** Creating BetterPlayer Cards panel which contains BetterPlayer cards */
    val botPlayerCards = new FlowPanel {
      preferredSize = new java.awt.Dimension(310, 60)
      opaque = false
      resizable = false
    }

    /**
     *  Creating BetterPlayer message box which displays Broke
     *  or BlackJack messages for Better Player
     */
    val botPlayerMsg = new FlowPanel {
      opaque = false
      resizable = false
    }

    /** Creating Playernames panel which contains Better and Human Payer Name panels */
    val playerNamesPanel = new FlowPanel() {
      contents += humanPlayerName
      contents += new Label { preferredSize = new java.awt.Dimension(370, 30) }
      contents += botPlayerName
      opaque = false
    }

    /** Creating PlayerCards panel which contains Better and Human Payer Name panels */
    val playerCardsPanel = new FlowPanel() {
      contents += humanPlayerCards
      contents += hGapPanel
      contents += botPlayerCards
      opaque = false
    }

    /** Creating PlayerMessage panel which contains Better and Human Payer Message panels */
    val playerMsgPanel = new FlowPanel() {
      preferredSize = new java.awt.Dimension(600, 60)
      contents += humanPlayerMsg
      contents += new Label { preferredSize = new java.awt.Dimension(400, 60) }
      contents += botPlayerMsg
      opaque = false
    }

    /** Creating AmountPanel panel and adding the contents of All the Buttons and Textfields in the GUI */
    val amountPanel = new FlowPanel() {
      contents += new Label { text = "BankRol $" }
      contents += bankRol
      contents += new Label { text = "Bet $" }
      contents += betAmount
      contents += new Label { text = "Seed" }
      contents += shuffleSeed
      contents += dealButton
      contents += hitButton
      contents += stayButton
      contents += doubleButton
      contents += quitButton
      background = new Color(58, 129, 159)
    }

    /** Creating a Menubar with File, Help and About BlackJack game */
    override val menuBar = new MenuBar {
      contents += new Menu("File") {
        contents += new MenuItem(Action("Exit") {
          System.exit(0)
        })
      }
      contents += new Menu("Help") {
        contents += new MenuItem(Action("Basic Strategy") {
          Dialog.showMessage(null, null, "Basic Strategy", Dialog.Message.Info, new ImageIcon("images/basicstrategy.gif"))
        })
      }
      contents += new Menu("About") {
        contents += new MenuItem(Action("About") {
          Dialog.showMessage(null, Config.About, "About", Dialog.Message.Info, new ImageIcon("images/BlackJackInfo.png"))
        })
      }
    }

    /** Creating a HumanPlayerPanel containing of all labels */
    val humanPlayerLabel = new BoxPanel(Orientation.Vertical) {
      contents += bankRolLabel
      contents += minBetLabel
      contents += maxBetLabel
      opaque = false
    }

    /** Creating a HumanPlayerPanel containing of all values corresponding to labels */
    val humanPlayerValue = new BoxPanel(Orientation.Vertical) {
      contents += bankRolValue
      contents += minBetValue
      contents += maxBetValue
      opaque = false
    }

    /** Creating a HumanplayerInfo panel containing of Label and value panels */
    val humanPlayerInfo = new FlowPanel {
      preferredSize = new java.awt.Dimension(300, 60)
      contents += humanPlayerLabel
      contents += humanPlayerValue
      opaque = false
      visible = false
    }

    /** Creating a BetterPlayerPanel containing of all labels */
    val botPlayerLabel = new BoxPanel(Orientation.Vertical) {
      contents += actionLabel
      contents += betAmtLabel
      contents += bankRollLabel
      opaque = false
    }

    /** Action Panel which shows BetterPlayers strategy action */
    val actionPanel = new FlowPanel {
      contents += actionValue
      opaque = false
    }

    /** Creating a BetterPlayerPanel containing of all values corresponding to labels */
    val botPlayerValue = new BoxPanel(Orientation.Vertical) {
      contents += actionPanel
      contents += betAmtValue
      contents += bankRollValue
      opaque = false
    }

    /** Creating a BetterplayerInfo panel containing of Label and value panels */
    val botPlayerInfo = new FlowPanel {
      preferredSize = new java.awt.Dimension(300, 60)
      contents += botPlayerLabel
      contents += botPlayerValue
      opaque = false
      visible = false
    }

    /** Creating a playerInfo panel to seperate the better and human player info panels */
    val playerInfoPanel = new BoxPanel(Orientation.Horizontal) {
      preferredSize = new java.awt.Dimension(200, 100)
      contents += new Label { preferredSize = new java.awt.Dimension(200, 100) }
      opaque = false
      resizable = false
    }

    /** Creating a InfoLayout panel */
    val infoLayout = new BorderPanel {
      add(humanPlayerInfo, West)
      add(playerInfoPanel, Center)
      add(botPlayerInfo, East)
      opaque = false
    }

    /** Creating a DealerLayout panel */
    val dealerLayout = new BoxPanel(Orientation.Vertical) {
      preferredSize = new java.awt.Dimension(500, 230)
      contents += dealerName
      contents += dealerCards
      contents += new Label { preferredSize = new java.awt.Dimension(450, 120); opaque = false }
      contents += playerNamesPanel
      opaque = false
    }

    /** Creating a PlayersLayout panel */
    val playersLayout = new BoxPanel(Orientation.Vertical) {
      preferredSize = new java.awt.Dimension(700, 120)
      contents += playerCardsPanel
      contents += playerMsgPanel
      opaque = false
    }

    /** Creating a BlackJackLayout */
    val BJLayout = new BorderPanel {
      add(dealerLayout, North)
      add(playersLayout, Center)
      add(infoLayout, South)

      bufferedImage = ImageIO.read(new File("images/BlackJackTable.jpg"))

      override def paintComponent(g: Graphics2D) =
        {
          super.paintComponent(g)
          if (null != bufferedImage) {
            g.drawImage(bufferedImage, 0, 0, null)
          }
        }
    }

    contents = new BorderPanel {
      add(menuBar, North)
      add(BJLayout, Center)
      add(amountPanel, South)
    }

    listenTo(dealButton)
    listenTo(hitButton)
    listenTo(stayButton)
    listenTo(doubleButton)
    listenTo(quitButton)

    reactions += {

      /** Starts the game by sending Human player info to House */
      case ButtonClicked(`dealButton`) =>
        println("Clicked dealButton button for Player id" + pid)

        var message = validateInputs()
        if (message.length == 0) {

          newDeal()

          betAmt = betAmount.text.toDouble
          seed = shuffleSeed.text.toInt

          try {

            house ! StartGame(pid, betAmt, seed)

            me ! NewBet(betAmt)

          } catch {
            case e: Exception =>
              message += "Please start the server and Login again"
              Dialog.showMessage(null, message, "Error", Dialog.Message.Error, new ImageIcon("images/bjzone.png"))
              System.exit(0)
          }

        } else {
          Dialog.showMessage(null, message, "Error", Dialog.Message.Error, new ImageIcon("images/bjzone.png"))
        }

      /** Listen to HitButton Clicked */
      case ButtonClicked(`hitButton`) =>
        println("Clicked hitButton button for Player id" + pid)
        playerHit()
        me ! Hit(pid)

      /** Listen to StayButton Clicked */
      case ButtonClicked(`stayButton`) =>
        println("Clicked stayButton button for Player id" + pid)
        playerStood()
        me ! Stay(pid)

      /** Listen to DoubleButton Clicked */
      case ButtonClicked(`doubleButton`) =>
        println("Clicked doubleButton button for Player id" + pid)
        if (bankRol.text.toDouble < (2 * betAmount.text.toDouble)) {
          val message = "Double Down is not Possible"
          Dialog.showMessage(null, message, "Error", Dialog.Message.Error, new ImageIcon("images/bjzone.png"))
          doubleButton.enabled = false
        } else {
          playerDoubled()
          me ! DoubleDown(pid)
        }

      /** Listen to QuitButton Clicked */
      case ButtonClicked(`quitButton`) =>
        println("Clicked QuitButton button for Player id" + pid)
        house ! Stop
        System.exit(0)
    }

    /** Pretty-prints the player reference */
    override def toString: String = "(" + playerName + ", " + pid + ")"
    actor {

      house ! AddHumanPlayer(playerName, newBankRoll, betAmt)

      loop {
        react {

          /** Receives a message from human player has logged in and his pid and display it */
          case LoggedIn(playerId: Int) =>
            me = select(Node(LoginScreen.SERVER, LoginScreen.PORT), Symbol(pid.toString))
            pid = playerId
            debug("Added player, received pid " + Symbol(playerId.toString))

          /** Receives a Table info and sets those variables in the GUI screen */
          case TableInfo(tid, minBet, maxBet) =>
            debug("Assigned table number:" + tid)
            minBetValue.text = minBet.toString
            maxBetValue.text = maxBet.toString
            betAmtValue.text = minBet.toString
            me = select(Node(LoginScreen.SERVER, LoginScreen.PORT), Symbol(pid.toString))
            debug(me + "")

          /** Receives a card form the HumanPlayer and displays it */
          case card: Card =>
            debug("I " + this + " received card " + card)
            showPlayerCard(card, pid, pid)

          /** Receives message about dealt card to other players */
          case Observe(card, player, size) =>
            debug("BotPlayer" + player + "received card " + card)
            showBotCard(card, player, size)

          /** Receives broke message */
          case Broke =>
            debug("Player Broke")
            playerBroke()
            humanPlayerMsg.contents += new Label { icon = new ImageIcon("images/playerbroke.png") }
            humanPlayerMsg.revalidate

          /** Receives the dealer's down-card and display it */
          case Hole(holecard) =>
            Thread.sleep(Config.delayTime)
            hGapPanel.visible = false
            hGapPanel.contents.clear
            hGapPanel.contents += new Label { text = "                " }
            hGapPanel.contents += new Label { icon = new ImageIcon("images/uppoint.gif") }
            hGapPanel.revalidate
            hGapPanel.visible = true
            dealerDownCard.icon = cardImage(holecard.toImageName)
            dealerCards.revalidate
            debug("Got Hole card - " + holecard)

          /** Receives the dealer's up-card and display it */
          case Up(upcard) =>
            dealerUpCard.icon = cardImage(upcard.toImageName)
            dealerCards.revalidate
            debug("Got Up card - " + upcard)
            if (!flag)
              playerTurn()

          /** Receives the player Black jacka and display the animation */
          case PlayerBlackJack =>
            debug("Player got BlackJack")
            humanPlayerMsg.contents += new Label { icon = new ImageIcon("images/BlackJack21.png") }
            humanPlayerMsg.revalidate
            playerBJ()

          /** Receives the Dealer Blackjack and display the animation */
          case DealerBlackJack =>
            dealerCards.contents += new Label { icon = new ImageIcon("images/BlackJack21.png") }
            dealerCards.revalidate
            debug("Dealer got BlackJack")

          /** Receives the Dealer Cards and display it */
          case DealerCard(card, dealer) =>
            showDealerCard(card, dealer)
            debug("Received dealer card " + card)

          /** Receives Dealer broke message  and display the animation */
          case DealerBroke(size) =>
            dealerCards.contents += new Label { icon = new ImageIcon("images/dealerbroke.jpg") }
            dealerCards.revalidate

          /** Receives BetterPlayer broke message and display the animation */
          case BetterPlayerBroke =>
            me = select(Node(LoginScreen.SERVER, LoginScreen.PORT), Symbol(pid.toString))
            debug("BetterPlayer Broke")
            botPlayerMsg.contents += new Label { icon = new ImageIcon("images/playerbroke.png") }
            botPlayerMsg.revalidate

          /** Receives BetterPlayer Blackjack message and display the animation */
          case BetterPlayerBlackJack =>
            me = select(Node(LoginScreen.SERVER, LoginScreen.PORT), Symbol(pid.toString))
            debug("BetterPlayer got BlackJack")
            botPlayerMsg.contents += new Label { icon = new ImageIcon("images/BlackJack21.png") }
            botPlayerMsg.revalidate

          /** Receives BetterPlayer's details and display it on the table */
          case BotPlayerDetail(bet, bank) =>
            debug(this + " received Better Player's gain: " + bet + " and bankroll: " + bank)
            bankRollValue.text = bank.toString

          /** Receives BetterPlayer's strategy and display it on the table */
          case ActionBot(action, tableNo) =>
            debug("BotPlayer action =" + action + " and the tableId is :" + tableNo)
            if (action.equals("D")) {
              actionPanel.contents += new Label {
                text = " D "
                font = new Font("Segoe UI Semibold", 0, 15)
                foreground = new java.awt.Color(255, 255, 255)
              }
            } else if (action.equals("S")) {
              actionPanel.contents += new Label {
                text = " S "
                font = new Font("Segoe UI Semibold", 0, 15)
                foreground = new java.awt.Color(255, 255, 255)
              }
            } else if (action.equals("H")) {
              actionPanel.contents += new Label {
                text = " H "
                font = new Font("Segoe UI Semibold", 0, 15)
                foreground = new java.awt.Color(255, 255, 255)
              }
            }

          /** Receives the Player won message and gain */
          case Win(money) =>
            Thread.sleep(Config.delayTime)
            Dialog.showMessage(null, "You Won! Your bankroll is $" + money, "Won", Dialog.Message.Info, new ImageIcon("images/won.gif"))
            bankRol.text = money.toString
            bankRolValue.text = money.toString
            gameOver()

          /** Receives the Player lost message and gain */
          case Lose(money) =>
            Thread.sleep(Config.delayTime)
            Dialog.showMessage(null, "You Lost! Your bankroll is $" + money, "Lost", Dialog.Message.Info, new ImageIcon("images/lose.gif"))
            bankRol.text = money.toString
            bankRolValue.text = money.toString
            gameOver()

          /** Receives the Player push message and gain */
          case Push(money) =>
            Thread.sleep(Config.delayTime)
            Dialog.showMessage(null, "You Pushed! Your bankroll is $" + money, "Pushed", Dialog.Message.Info, new ImageIcon("images/push.gif"))
            bankRol.text = money.toString
            bankRolValue.text = money.toString
            gameOver()
        }
      }
    }
    centerOnScreen()
    visible = true
  }

  /** Validating input entered by the User and if any wrong input it prompts the user for correction */
  def validateInputs(): String = {

    var message = ""

    if (mainFrame.betAmount.text == "") { message += "\n Enter Bet Amount" }

    if (mainFrame.shuffleSeed.text == "") { message += "\n Enter Shuffle Seed 0-9" }

    var isBetAmtNumeric = false
    try {
      mainFrame.betAmount.text.toDouble
      isBetAmtNumeric = true
    } catch {
      case e: Exception => isBetAmtNumeric = false
    }

    var isSeedNumeric = false
    try {
      mainFrame.shuffleSeed.text.toDouble
      isSeedNumeric = true
    } catch {
      case e: Exception => isSeedNumeric = false
    }

    try {

      if (mainFrame.betAmount.text.toDouble > mainFrame.bankRol.text.toDouble) { message += "\n Bet amount value should be less than bankroll" }
    } catch {
      case e: Exception => message += ""
    }

    if (!isSeedNumeric) { message += "\n Seed must be a numeric value" }

    else if (mainFrame.shuffleSeed.text.toDouble > 9) { message += "\n Maximum shuffle seed allowed is 9" }

    if (!isBetAmtNumeric) { message += "\n Bet amount must be a numeric value." }

    else if (mainFrame.betAmount.text.toDouble < 5) { message += "\n Minimum bet amount allowed is $5" }

    else if (mainFrame.betAmount.text.toDouble > 200) { message += "\n Maximum bet amount allowed is $200" }

    message

  }

  /** Displays HumanPlayer Cards */
  def showPlayerCard(card: Card, player: Int, hand: Int): Unit = {
    debug("Showing human Player id = " + player + " card = " + card)
    mainFrame.humanPlayerCards.contents += new Label { icon = cardImage(card.toImageName) }
    mainFrame.humanPlayerCards.revalidate
    Thread.sleep(Config.sleepTime)
  }

  /** Displays BetterPlayer Cards */
  def showBotCard(card: Card, player: Int, hand: Int): Unit = {
    debug("Showing better Player id = " + player + " card = " + card)
    mainFrame.botPlayerCards.contents += new Label { icon = cardImage(card.toImageName) }
    mainFrame.botPlayerCards.revalidate
    Thread.sleep(Config.sleepTime)
  }

  /** Displays Dealer Cards */
  def showDealerCard(card: Card, dealer: Int): Unit = {
    debug("Showing dealer id = " + dealer + " card = " + card)
    mainFrame.dealerCards.contents += new Label { icon = cardImage(card.toImageName) }
    mainFrame.dealerCards.revalidate
    Thread.sleep(Config.sleepTime)
  }

  /** Method to converting card string imageIcon  */
  def cardImage(cardFile: String): ImageIcon = {
    val myImg = new ImageIcon("images/cards/" + cardFile + ".png")
    val img = myImg.getImage();
    val newImg = img.getScaledInstance(40, 54, java.awt.Image.SCALE_SMOOTH)
    val bjImg = new ImageIcon(newImg)
    bjImg
  }

  /** For Every new Game it does the following  */
  def newDeal(): Unit = {
    clear
    mainFrame.hGapPanel.contents += new Label { text = "      " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/waiting.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.dealButton.enabled = false
    mainFrame.hitButton.enabled = false
    mainFrame.stayButton.enabled = false
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.betAmount.editable = false
    mainFrame.shuffleSeed.editable = false
    mainFrame.botPlayerInfo.visible = true
    mainFrame.humanPlayerInfo.visible = true
    mainFrame.actionPanel.contents.clear
    mainFrame.actionValue.text = "-";
  }

  /** For player turn it does the following  */
  def playerTurn(): Unit = {
    mainFrame.dealButton.enabled = false
    mainFrame.hitButton.enabled = true
    mainFrame.stayButton.enabled = true
    mainFrame.doubleButton.enabled = true
    mainFrame.quitButton.enabled = false
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "           " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/leftpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
  }

  /** When the Gameover happens then it does the following  */
  def gameOver(): Unit = {
    mainFrame.hitButton.enabled = false
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = true
    mainFrame.stayButton.enabled = false
    mainFrame.dealButton.enabled = true
    mainFrame.betAmount.editable = true
    mainFrame.shuffleSeed.editable = true
    mainFrame.actionPanel.contents.clear
    mainFrame.actionValue.text = "-";
    flag = false
    clear
  }

  /** When the PlayerBroke then it does the following  */
  def playerBroke(): Unit = {
    mainFrame.hitButton.enabled = false
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.dealButton.enabled = false
    mainFrame.stayButton.enabled = false
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "            " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/rightpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
  }

  /** When the Player click stay then it does the following  */
  def playerStood(): Unit = {
    mainFrame.hitButton.enabled = false
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.dealButton.enabled = false
    mainFrame.stayButton.enabled = false
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "            " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/rightpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
  }

  /** When the Player click Double then it does the following  */
  def playerDoubled(): Unit = {
    mainFrame.hitButton.enabled = false
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.dealButton.enabled = false
    mainFrame.stayButton.enabled = false
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "            " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/rightpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
  }

  /** When the Player click Hit then it does the following  */
  def playerHit(): Unit = {
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "            " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/leftpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.dealButton.enabled = false
  }

  /** When the Player get Blackjack then it does the following  */
  def playerBJ(): Unit = {
    mainFrame.doubleButton.enabled = false
    mainFrame.quitButton.enabled = false
    mainFrame.dealButton.enabled = false
    mainFrame.hitButton.enabled = false
    mainFrame.stayButton.enabled = true
    mainFrame.hGapPanel.visible = false
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.contents += new Label { text = "           " }
    mainFrame.hGapPanel.contents += new Label { icon = new ImageIcon("images/leftpoint.gif") }
    mainFrame.hGapPanel.revalidate
    mainFrame.hGapPanel.visible = true
    flag = true
  }

  /** After each game it resets the following  */
  def clear(): Unit = {
    mainFrame.dealerCards.visible = false
    mainFrame.humanPlayerCards.visible = false
    mainFrame.botPlayerCards.visible = false
    mainFrame.hGapPanel.visible = false
    mainFrame.humanPlayerMsg.visible = false
    mainFrame.botPlayerMsg.visible = false

    mainFrame.dealerCards.contents.clear
    mainFrame.dealerCards.revalidate
    mainFrame.humanPlayerCards.contents.clear
    mainFrame.humanPlayerCards.revalidate
    mainFrame.botPlayerCards.contents.clear
    mainFrame.botPlayerCards.revalidate
    mainFrame.humanPlayerMsg.contents.clear
    mainFrame.humanPlayerMsg.revalidate
    mainFrame.botPlayerMsg.contents.clear
    mainFrame.botPlayerMsg.revalidate
    mainFrame.hGapPanel.contents.clear
    mainFrame.hGapPanel.revalidate

    mainFrame.dealerUpCard.icon = cardImage("back1")
    mainFrame.dealerDownCard.icon = cardImage("back")
    mainFrame.dealerCards.contents += mainFrame.dealerUpCard
    mainFrame.dealerCards.contents += mainFrame.dealerDownCard
    mainFrame.dealerCards.visible = true
    mainFrame.humanPlayerCards.visible = true
    mainFrame.botPlayerCards.visible = true
    mainFrame.hGapPanel.visible = true
    mainFrame.humanPlayerMsg.visible = true
    mainFrame.botPlayerMsg.visible = true
  }

}


  
  
